home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / compress / tar321__.zip / SOURCES.ZIP / SAVEFILE.C < prev    next >
C/C++ Source or Header  |  1997-03-24  |  9KB  |  320 lines

  1. /* savefile.c - storying regular files into (tape) archive
  2.  * This is the part of the Tar program (see file tar.c)
  3.  * Author: T.V.Shaporev
  4.  * Creation date 11 Mar 1993
  5.  */
  6. #include <stdio.h>
  7.  
  8. #include "sysup.h"
  9. #include "modern.h"
  10. #include "compress.h"
  11. #include "zippipe.h"
  12. #include "crc32.h"
  13. #include "define.h"
  14.  
  15. extern char longname[];
  16.  
  17. extern char *deleft __ARGS__(( char * ));
  18. extern void newhead __ARGS__(( char *, long ));
  19. extern void prcsum  __ARGS__(( register header * ));
  20. extern void proctl  __ARGS__(( char *, long ));
  21. static void prhexl  __ARGS__(( char *, long ));
  22.  
  23. static void prhexl(dest, l)
  24. char *dest; long l;
  25. {
  26.    register int i;
  27.    static char h[] = "0123456789AbCdEf";
  28.  
  29.    *dest++ = '0'; *dest++ = 'x';
  30.    for (i=32; i;) *dest++ = h[(int)(l >> (i -= 4)) & 15];
  31.    *dest++ = ' '; *dest++ = '\0';
  32. }
  33.  
  34. #ifdef UNIX
  35.     static werelost = FALSE;
  36. #endif
  37.  
  38. #ifdef MSDOS
  39. #    include <string.h>
  40. #else
  41.     int  strlen();
  42.     char *strcpy(), *strcat(), *strncpy();
  43.     int  open(), read(), close(), unlink();
  44.     long lseek();
  45. #endif
  46. #include "lzpack.h"
  47. #include "roll.h"
  48.  
  49. void cantopen(name)
  50. char *name;
  51. {
  52.    (void)fprintf(myout, "Tar: can\'t open \'%s\'\n", name);
  53. }
  54.  
  55. static void tmpput  __ARGS__(( int ));
  56. static void no_mem  __ARGS__(( int ));
  57. static void errproc __ARGS__(( char * ));
  58.  
  59. static void tmpput(c)
  60. int c;
  61. {
  62.    ++codesize; if (rputc(c) != 0) errproc(hblock->m.name);
  63. }
  64.  
  65. static void no_mem(flag)
  66. int flag;
  67. {
  68.    (void)fprintf(stderr, "No memory for encoding.");
  69.    if (flag) {
  70.       (void)fprintf(stderr, " Continue? ");
  71.       if (YES_NO()) return;
  72.    } else {
  73.       (void)fprintf(stderr, "\n");
  74.    }
  75.    done(ESMALL);
  76. }
  77.  
  78. static void errproc(fname)
  79. char *fname;
  80. {
  81.    (void)fprintf(myout, "\nTar: error processing \'%s\'\n", fname);
  82.    done(EINTER);
  83. }
  84.  
  85. void savefile(fname)
  86. char *fname;
  87. {
  88.    register i; register c;
  89.    register char *p;
  90.    register long blocks;
  91.    register packok;
  92.    register node *t; node *prev;
  93.    int infile; long this;
  94.  
  95.    p = deleft(fname);
  96.    if (u_flag) {
  97.       if ((t = finditem(p, &prev, timehead)) != NONE) {
  98.          i = t->info.time >= st.st_mtime;
  99.          delitem(t, &timehead);
  100.          if (i) return;
  101.       }
  102.    }
  103.    if (isfile) { /* compare file to store with the archive */
  104. #ifdef UNIX
  105.       if (st.st_ino == sa.st_ino && st.st_dev == sa.st_dev) return;
  106. #endif
  107. #ifdef MSDOS
  108.       if (isarchive(&st, fname)) return;
  109. #endif
  110.    }
  111.    if (w_flag && !okwork('a', ' ', &st, fname)) return;
  112. #ifdef MSDOS
  113.    infile = open(fname + fnoffset(fname), OM_RDONLY);
  114. #else
  115.    infile = open(fname, OM_RDONLY);
  116. #endif
  117.    if (infile < 0) {
  118.       cantopen(fname); return;
  119.    }
  120.    newhead(p, st.st_size);
  121. #ifdef UNIX
  122.    if (st.st_nlink > 1) {
  123.       prev = t = linkhead; i = 1;
  124.       while (t && i>0) {
  125.          i = st.st_ino - t->info.data.inode;
  126.          if (!i) i = st.st_dev - t->info.data.device;
  127.          if (i>0) { prev = t; t = t->next; }
  128.       }
  129.       if (i || !t) {/* entry not found */
  130.          if ((t = additem(p, prev, &linkhead)) == NONE) {
  131.             if (!werelost) {
  132.                (void)fprintf(myout,
  133.                              "Tar: out of memory; link(s) lost\n");
  134.                werelost = TRUE;
  135.             }
  136.          } else {
  137.             t->info.data.count  = st.st_nlink - 1;
  138.             t->info.data.device = st.st_dev;
  139.             t->info.data.inode  = st.st_ino;
  140.          }
  141.       } else {/* previous entry found */
  142.          (void)strncpy(hblock->m.linkname, t->name, MAXTNAME);
  143.          hblock->m.filetype = TF_LNK;
  144.          prcsum(hblock);
  145.          if (v_flag) {
  146.             (void)fprintf(myout, "a %s link to %s\n", p, t->name);
  147.          }
  148.          if (--(t->info.data.count) < 1) delitem(t, &linkhead);
  149.          (void)close(infile);
  150.          return;
  151.       }
  152.    }
  153. #endif
  154.    blocks = (st.st_size + (BLKSIZE-1)) / BLKSIZE;
  155.    packok = FALSE;
  156.    if (blocks > 1) {
  157.       if (pktype == PKDEF) {
  158.          if (zipalloc()!=0 || newroll("TAROLLXXXXXX")!=0) {
  159.             delroll();
  160. #ifndef MSDOS
  161.             if (!w_flag) {
  162.                no_mem(0);
  163.             } else
  164. #endif
  165.             {
  166.                no_mem(1);
  167.                pktype = PKNONE;
  168.                goto run;
  169.             }
  170.          }
  171.          (void)rewroll(0);
  172.          if (v_flag) (void)fprintf(stderr, "e %s", p);
  173.          (void)fflush(stderr);
  174.  
  175.          if (zipcreat(tmpput, ZIP_RAW, ziplevel) != 0) {
  176.             (void)fprintf(stderr, "Zip error: %s\n", ziperrlist[ziperror]);
  177.             done(EINTER);
  178.          }
  179.          this = 0;
  180.          do {
  181.             if ((i = read(infile, pk_inp, pksize)) < 0) {
  182.                errproc(hblock->m.name);
  183.             }
  184.             if (i > 0) {
  185.                (void)zipwrite(pk_inp, i);
  186.                if (v_flag) percent((this += i), st.st_size);
  187.             }
  188.          } while (i == pksize);
  189.          codesize = zipclose();
  190.       }
  191. #ifdef USE_COMPRESS
  192.       else if (pktype == PKfLZW) {
  193.          if (strlen(hblock->m.name) > MAXTNAME-2) {
  194. #ifndef MSDOS
  195.             if (!w_flag) {
  196.                (void)fprintf(stderr, longname, hblock->m.name);
  197.             } else
  198. #endif
  199.             {
  200.                (void)fprintf(stderr,
  201.                   "Tar: name \'%s\' too long. Store uncompressed? ",
  202.                   hblock->m.name);
  203.                if (YES_NO()) goto run;
  204.             }
  205.             return;
  206.          }
  207.          if (newroll("TAROLLXXXXXX")!=0) {
  208.             delroll();
  209. #ifndef MSDOS
  210.             if (!w_flag) {
  211.                no_mem(0);
  212.             } else
  213. #endif
  214.             {
  215.                no_mem(1);
  216.                pktype = PKNONE;
  217.                goto run;
  218.             }
  219.          }
  220.          if ((i = z_gettab(lzwbits)) < lzwbits) {
  221.             if (i > 0) {
  222. #ifndef MSDOS
  223.                if (!w_flag) {
  224.                   (void)fprintf(stderr, "Can only handle %d bits.\n", i);
  225.                   lzwbits = i;
  226.                } else
  227. #endif
  228.                {
  229.                   (void)fprintf(stderr,
  230.                            "Can only handle %d bits. Continue? ", i);
  231.                   lzwbits = YES_NO() ? i : -1;
  232.                }
  233.             }
  234.             if (i <= 0) {
  235.                no_mem(1);
  236.                z_reltab();
  237.                pktype = PKNONE;
  238.                goto run;
  239.             }
  240.          }
  241.          (void)rewroll(0);
  242.          if (v_flag) (void)fprintf(stderr, "z %s", p);
  243.          (void)fflush(stderr);
  244.  
  245.          if (cbegin(lzwbits, tmpput, st.st_size) < lzwbits) no_mem(0);
  246.          this = 0;
  247.          do {
  248.             if ((i = read(infile, pk_inp, pksize)) < 0) {
  249.                errproc(hblock->m.name);
  250.             }
  251.             if (i > 0) {
  252.                cpiece(pk_inp, i);
  253.                if (v_flag) percent((this += i), st.st_size);
  254.             }
  255.          } while (i == pksize);
  256.          codesize = cflush();
  257.       }
  258. #endif
  259.       if (v_flag) (void)fprintf(stderr, "\r");
  260.       if (pkfile) {
  261.          register long b;
  262.  
  263.          if ((b = (codesize + (BLKSIZE-1)) / BLKSIZE) < blocks) {
  264.             packok = TRUE;
  265.             blocks = b;
  266.          } else if (lseek(infile, 0L, 0) < 0) {
  267.             (void)fprintf(myout, "Tar: \'%s\' seek error\n", fname);
  268.             done(ERREAD);
  269.          }
  270.       }
  271.    }
  272. run : if (v_flag || j_flag) {
  273.       (void)fprintf(myout, "a %s %ld blocks\n", p, blocks);
  274.    }
  275.    if (j_flag) {
  276.       (void)fprintf(stderr, "> ");
  277.       for (i=0; (c=getc(myinp))!='\n'; ) {
  278.          if (i < sizeof(hblock->m.comment)-1) {
  279.             hblock->m.comment[i++] = c;
  280.          }
  281.       }
  282.       hblock->m.comment[i] = 0;
  283.    } else {
  284.       hblock->m.comment[0] = 0;
  285.    }
  286.    if (packok) {
  287.       proctl(hblock->m.size, codesize);
  288.       if (pktype == PKfLZW) {
  289.          (void)strcat(hblock->m.name, ".Z");
  290.       } else { /* pktype == PKDEF */
  291.          prhexl(hblock->m.srcsum, getcrc());
  292.          prhexl(hblock->m.srclen, st.st_size);
  293.       }
  294.       prcsum(hblock);
  295.  
  296.       if (rewroll(1) != 0) errproc(p);
  297.       while (codesize-- > 0) {
  298.          if ((c = rgetc()) == EOF) errproc(p);
  299.          writebyte(c);
  300.       }
  301.    } else {/* common store file */
  302.       prcsum(hblock);
  303.  
  304.       if ((blocks -= writearch(infile, st.st_size, fname)) != 0) {
  305.          (void)fprintf(myout, "Tar: \'%s\' decreased size\n", fname);
  306.          while (blocks-- > 0) nullblock(steptape());
  307.       }
  308.    }
  309.    (void)close(infile);
  310.  
  311.    if (y_flag) {
  312. #ifdef MDSOS
  313.       if (!(st.st_mode & S_IWRITE)) (void)chmod(fname, S_IWRITE);
  314. #endif
  315.       if (unlink(fname)) {
  316.          (void)fprintf(myout, "Tar: can\'t delete \'%s\'\n", fname);
  317.       }
  318.    }
  319. }
  320.